from rest_framework.views import APIView
from rest_framework.viewsets import GenericViewSet
from rest_framework.filters import OrderingFilter
from django_filters import rest_framework as filters
from django.conf import settings
from django.core.cache import cache
from md5 import get_password_hash
from mixins import MyListModelMixin, MyDestroyModelMixin, MyCreateModelMixin, MyUpdateModelMixin
from pagination import MyPageNumberPagination
from .serializers import LoginSerializers, UserSerializers
from .filter import UserProductFilter
from .models import Users, UserToRole
from role.models import RoleToMenu
from response import APIResponse
from status import *
from format import menus_to_tree
from auth import create_token, JwtTokenAuthentication
from permission import MyPermissions
import datetime
import re


class Login(APIView):
    def post(self, request):
        res = LoginSerializers(data=request.data)
        if res.is_valid():
            username = res.data.get("username")
            password = get_password_hash(res.data.get("password"))  # password转换成md5
            if re.match(r"^1[3-9]\d{9}$", username):
                user_obj = Users.objects.filter(phone=username, password=password).first()
            elif re.match(r"^[a-zA-Z0-9_-]+@[a-zA-Z0-9_-]+(\.[a-zA-Z0-9_-]+)+$", username):
                user_obj = Users.objects.filter(email=username, password=password).first()
            else:
                user_obj = Users.objects.filter(username=username, password=password).first()
            if user_obj:
                role_data, role_ids = self.get_role(user_obj.id)
                menu_tree, menus_obj = self.get_menu(role_ids)
                cache.set(f"{user_obj.id}_menus", menus_obj, settings.CACHES_EXPIRE)
                data = {
                    "id": user_obj.id,
                    "username": user_obj.username,
                    "nickname": user_obj.nickname,
                    "roles": role_data,
                    "menus": menu_tree,
                    "last_login": user_obj.last_login,
                    "token": create_token(user_obj.id, username, 3),  # token有效期3天
                }
                user_obj.last_login = datetime.datetime.now()
                user_obj.save()
                return APIResponse(code=SUCCESS, msg="登录成功", data=data)
            return APIResponse(code=ERROR, msg="账号或密码错误")
        return APIResponse(code=ERROR, msg=res.errors)

    # 获取角色
    def get_role(self, user_id):
        user_roles = UserToRole.objects.filter(user_id=user_id).all()
        roles_data = [
            {"role_id": user_role.role.id, "role_name": user_role.role.name, "description": user_role.role.description}
            for user_role in user_roles]
        role_ids = [user_role.role.id for user_role in user_roles]
        return roles_data, role_ids

    # 获取菜单
    def get_menu(self, role_ids):
        menu_list = []
        for role_id in role_ids:
            role_menus = RoleToMenu.objects.filter(role_id=role_id).all()
            for role_menu in role_menus:
                menu_list.append(role_menu.menu)

        # 考虑到菜单可能重复
        menus = set(menu_list)
        menu_tree = menus_to_tree(menus)
        return menu_tree, menus


class UserViews(MyListModelMixin, MyDestroyModelMixin, MyCreateModelMixin, MyUpdateModelMixin, GenericViewSet):
    queryset = Users.objects.filter(is_deleted=False).all().order_by("-id")
    pagination_class = MyPageNumberPagination
    serializer_class = UserSerializers
    authentication_classes = [JwtTokenAuthentication]
    permission_classes = [MyPermissions]
    filter_backends = [OrderingFilter, filters.DjangoFilterBackend]
    filterset_class = UserProductFilter
    ordering_fields = ['id']
    filter_fields = ('username', 'nickname', 'updated_at', 'created_at')

    def perform_destroy(self, instance):
        user_role_obj_all = UserToRole.objects.filter(user=instance).all()
        for user_role_obj in user_role_obj_all:
            if user_role_obj.role.id == 1:
                return APIResponse(code=ERROR, msg="超级管理员无法删除")
        instance.is_deleted = True
        instance.save()

    def perform_create(self, serializer):
        role_ids = serializer.validated_data.pop('role_ids')
        user = serializer.save()

        # 使用bulk_create 给用户批量增加角色
        role_list = [UserToRole(user=user, role_id=role_id) for role_id in role_ids]
        UserToRole.objects.bulk_create(role_list)

    def perform_update(self, serializer):
        role_ids = serializer.validated_data.pop('role_ids')
        user = serializer.save()

        # 1.先删除当前用户的所有角色
        UserToRole.objects.filter(user=user).delete()
        # 2.使用bulk_create 给用户批量增加角色
        role_list = [UserToRole(user=user, role_id=role_id) for role_id in role_ids]
        UserToRole.objects.bulk_create(role_list)
